#include <CyberLib.h>

#define motors_init {D4_Out; D5_Out; D6_Out; D7_Out;}
#define robot_go {D4_Low; D5_High; D6_High; D7_Low;}
#define robot_back {D4_High; D5_Low; D6_Low; D7_High;}
#define robot_stop {D4_Low; D5_Low; D6_Low; D7_Low;}
#define robot_rotation_left {D4_Low; D5_High; D6_Low; D7_High;}
#define robot_rotation_right {D4_High; D5_Low; D6_High; D7_Low;}

#define size_buff 5 //размер массива sensor
uint16_t sensor[size_buff]; //массив для хранения замеров дальномера
uint8_t stat=0; //направление разворота
int runSpeedHIGH = 180;
int runSpeedLOW = 60;
int LED = 13;      // LED подключен к 12 пину
int leftDirPin = 4;
int leftSpeedPin = 5;
int rightDirPin = 7;
int rightSpeedPin = 6;

void setup()  
{
  motors_init;  //инициализация выходов моторов
  D11_Out;  D11_Low;    //динамик
  D14_Out; D14_Low; //пин trig ультразвукового сонара
  D15_In;     //пин echo  ультразвукового сонара
  randomSeed(A6_Read); //Получить случайное значение
  for(uint8_t i=0; i<12; i++) beep(70, random(100, 2000)); //звуковое оповещение готовности робота
  wdt_enable(WDTO_500MS);    //Сторожевая собака 0,5сек.
  pinMode(LED, OUTPUT); //светодиод
}

void loop()
{Start  
  uint16_t dist=GetDistance(); //производим замер дистанции

    if( dist < 10) {
        digitalWrite(LED, LOW);
        rotation(stat, 255);
  } else   //если 10см максимальный угол разворота
    if( dist < 20) {
        digitalWrite(LED, LOW);
        rotation(stat, 200);
  } else   //если 20см  средний угол разворота
    if( dist < 40) {
       digitalWrite(LED, LOW);
       rotation(stat, 130);
  } else   //если 40см  минимальный угол разворота
                   {
        digitalWrite(LED, HIGH);
        digitalWrite(leftDirPin, LOW);
        digitalWrite(rightDirPin, LOW);
        analogWrite(leftSpeedPin, runSpeedHIGH);
        analogWrite(rightSpeedPin, runSpeedHIGH);
        stat=~stat;
               }       //поехали!!!      
     wdt_reset(); //покормить собаку
End;}
//***************************************************
void rotation(uint8_t arr, uint8_t dur) 
{
    switch (arr) //смотрим в каком направление разворачиваться
    {
    case 0:
      digitalWrite(leftDirPin, LOW);
      digitalWrite(rightDirPin, HIGH);
      analogWrite(leftSpeedPin, runSpeedHIGH);
      analogWrite(rightSpeedPin, runSpeedLOW);
      break;
    case 255:
        digitalWrite(leftDirPin, HIGH);
        digitalWrite(rightDirPin, LOW);
        analogWrite(leftSpeedPin, runSpeedLOW);
        analogWrite(rightSpeedPin, runSpeedHIGH);
      break;    
    } 
    delay_ms(dur);    //угол разворота
    robot_stop;      //стоп мотор!
}
//***************************************************
uint16_t GetDistance() 
{
 uint16_t dist;
 for (uint8_t i = 0; i < size_buff; ++i) //производим несколько замеров
  { 
    D14_High; delay_us(10);  D14_Low;  //запустить измерение
   dist = pulseIn(15, HIGH, 2400); //считываем длительность времени прохождения эха, ограничить время ожидания
   if(dist==0) dist=2400;  
   sensor[i]=dist;  //сохранить в массиве
   delay_ms(40); //задержка между посылками
   wdt_reset(); //покормить собаку, что бы она не сбежала 
  }
  dist=(find_similar(sensor, size_buff, 58))/58; // //фильтруем показания датчика и переводим в см
  return dist;
} 
